#include "winobject.h"

#include <windows.h>
#include <process.h>

using namespace kog;
using namespace kog::os;

osobject::osobject(void)
: _handle(NULL)
{
}

osobject::osobject(winhandle handle)
: _handle(handle)
, _type(none)
{
}

osobject::~osobject(void)
{
}

void osobject::close()
{
	if (is_valid() && _type != thread)
	{
		CloseHandle((HANDLE)_handle);
	}
	_handle = NULL;
}

void osobject::sleep(int ms)
{
	Sleep(ms);
}

osobject& osobject::create_semaphore(long initCount, long maxCount)
{
	HANDLE hSemp = ::CreateSemaphore(NULL, initCount, maxCount, NULL);
	_type = semaphore;
	_handle = (void*)hSemp;
	return *this;
}

osobject& osobject::create_event(bool initOwn, bool manualReset)
{
	HANDLE hEvent = ::CreateEvent(NULL, manualReset, initOwn, NULL);
	_type = xevent;
	_handle = (void*)hEvent;
	return *this;
}

osobject& osobject::create_mutex(bool initOwn)
{
	HANDLE hMutex = ::CreateMutex(NULL, initOwn ? TRUE : FALSE, NULL);
	_type = mutex;
	_handle = (void*)hMutex;
	return *this;
}

int osobject::wait(int timeout)
{
	return ::WaitForSingleObject(_handle, timeout);
}

bool osobject::release()
{
	BOOL ret = FALSE;
	switch (_type)
	{
	case mutex:
		ret = ::ReleaseMutex(_handle);
		break;
	case semaphore:
		ret = ::ReleaseSemaphore(_handle, 1, NULL);
		break;
	case xevent:
		ret = ::SetEvent(_handle);
		break;
	default:
		break;
	}
	return ret == TRUE;
}

bool osobject::is_valid() const
{
	return _handle != NULL && _handle != INVALID_HANDLE_VALUE;
}

osobject::winhandle osobject::get() const
{
	return _handle;
}

osobject::handle_type osobject::htype() const
{
	return _type;
}

osobject& osobject::reset(winhandle handle)
{
	_handle = handle;
	return *this;
}

void osobject::_create_thread(ithread* p)
{
	_handle = (winhandle)_beginthread(&ithread::entry_function, 0, p);
	_type = thread;
}